using System;
using System.Collections.Generic;
using System.Text;


namespace TidhiGanitam.DataModel
{
    public class Degree : DegreeEntity
    {
        #region properties
        public double Degrees
        {
            get
            {
                double dDeg = MathHelper.GetDegrees(dDegrees);
                return dDeg % 360;
            }
        }
        public double Minutes
        {
            get
            {
                return MathHelper.GetMinutes(dDegrees);
            }
        }
        public double Seconds
        {
            get
            {
                return MathHelper.GetSeconds(dDegrees);
            }
        }
        public override string ToString()
        {
            string sRetString = string.Empty;
            sRetString = string.Format("{3}{0}-{1}-{2}", Degrees.ToString(),
                                                Minutes.ToString(),
                                                Seconds.ToString(),
                                                dDegrees>=0?"":"-");
            return sRetString;
        }

        #endregion
        public Degree()
            : base()
        { 
        }
        public Degree(Degree degree)
            :base((DegreeEntity)degree)
        {
        }
        public Degree(double degrees, double minutes, double seconds, double milliseconds)
            :base(degrees, minutes, seconds,milliseconds)
        {
        }
        public Degree(double degrees, double minutes, double seconds)
            : base(degrees, minutes, seconds, 0)
        {
        }
        public Degree(double degrees, double minutes)
            :base(degrees, minutes, 0, 0)
        {
        }
        public Degree(double degrees)
            :base(degrees)
        {
        }

        #region operator overloading routines

        public static Degree operator +(Degree op1, Degree op2)
        {
            Degree RetVal = new Degree();
            RetVal.dDegrees = op1.dDegrees + op2.dDegrees;
            RetVal.Refresh();
            return RetVal;
        }
        public static Degree operator +(Degree op1, double op2)
        {
            Degree RetVal = new Degree();
            RetVal.dDegrees = op1.dDegrees + op2;
            RetVal.Refresh();
            return RetVal;
        }
        public static Degree operator -(Degree op1, Degree op2)
        {
            Degree RetVal = new Degree();
            if (op1 < op2)
            {
                op1.dDegrees += 360d;
            }
            RetVal.dDegrees = op1.dDegrees - op2.dDegrees;
            RetVal.Refresh();
            return RetVal;
        }
        public static Degree operator -(Degree op1, double op2)
        {
            Degree RetVal = new Degree();
            if (op1.dDegrees < op2)
            {
                op1.dDegrees += 360d;
            }
            RetVal.dDegrees = op1.dDegrees - op2;
            RetVal.Refresh();
            return RetVal;
        }
        public static Degree operator *(Degree op1, Degree op2)
        {
            Degree RetVal = new Degree();
            RetVal.dDegrees = op1.dDegrees * op2.dDegrees;
            RetVal.Refresh();
            return RetVal;
        }
        public static Degree operator *(Degree op1, double op2)
        {
            Degree RetVal = new Degree();
            RetVal.dDegrees = op1.dDegrees * op2;
            RetVal.Refresh();
            return RetVal;
        }
        public static Degree operator /(Degree op1, Degree op2)
        {
            Degree RetVal = new Degree();
            if (op2.dDegrees != 0)
            {
                RetVal.dDegrees = op1.dDegrees / op2.dDegrees;
            }
            RetVal.Refresh();
            return RetVal;
        }
        public static Degree operator /(Degree op1, double op2)
        {
            Degree RetVal = new Degree();
            if (op2 != 0)
            {
                RetVal.dDegrees = op1.dDegrees / op2;
            }
            RetVal.Refresh();
            return RetVal;
        }
        public static bool operator >(Degree op1, Degree op2)
        {
            bool ReturnValue = false;
            if (op1.dDegrees > op2.dDegrees)
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }
        public static bool operator >=(Degree op1, Degree op2)
        {
            bool ReturnValue = false;
            if (op1.dDegrees >= op2.dDegrees)
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }
        public static bool operator ==(Degree op1, Degree op2)
        {
            bool ReturnValue = false;
            if (op1.dDegrees == op2.dDegrees)
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }
        public static bool operator <(Degree op1, Degree op2)
        {
            bool ReturnValue = false;
            if (op1.dDegrees < op2.dDegrees)
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }
        public static bool operator <=(Degree op1, Degree op2)
        {
            bool ReturnValue = false;
            if (op1.dDegrees < op2.dDegrees)
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }
        public static bool operator !=(Degree op1, Degree op2)
        {
            bool ReturnValue = false;
            if (op1.dDegrees != op2.dDegrees)
            {
                ReturnValue = true;
            }
            return ReturnValue;
        }
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
#endregion

        public void Refresh()
        {
            this.dDegrees = dDegrees % 360;
        }
        public static Degree AbsoluteDifference(Degree op1, Degree op2)
        {
            double dDiff =Math.Abs(op1.dDegrees - op2.dDegrees);
            return new Degree(dDiff);
        }
        public static Degree Difference(Degree op1, Degree op2)
        {
            return new Degree(op1.dDegrees - op2.dDegrees);
        }
        public double RawValue
        {
            get { return dDegrees; }
        }
    }
}
